﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using System.Text;

using JoyServer.Events;
using JoyServer.Input;
using JoyServer.Net;

namespace JoyServer
{

	/// <summary>
	/// プログラムのメインとなる部分
	/// </summary>
	class Main
	{
		/// <summary>
		/// ジョイスティックの状態を送信する用の TCP サーバ
		/// </summary>
		private TcpServer tcpServer;

		/// <summary>
		/// ポリシーファイルを送信するサーバ
		/// crossdomain.xml ファイルを Flash 側に送信する
		/// </summary>
		private PolicyFileServer policyServer;

		/// <summary>
		/// タスクバーアイコンと右クリックメニューを
		/// 表示するためのフォーム
		/// </summary>
		private FormMain formMain;

		/// <summary>
		/// コンストラクタ
		/// </summary>
		public Main()
		{
			// デバッグ用
			// カレントディレクトリ表示
			Debug.WriteLine("カレントディレクトリ: " + Directory.GetCurrentDirectory());

			// サーバの初期化
			tcpServer = new TcpServer(TcpServer.DEFAULT_PORT);
			policyServer = new PolicyFileServer(PolicyFileServer.DEFAULT_PORT);

			// ロガーの初期化
			Global.logger = new Logger();

			// サーバの開始
			start();

			// GUI 表示用の設定
			//Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);

			// タスクバーアイコン用フォームの表示
			formMain = new FormMain();
			formMain.addEventListener(FormEvent.LOAD, onLoad);
			formMain.addEventListener(FormEvent.FORM_CLOSING, onClosing);
			//formMain.start();

			Application.Run(formMain);
		}

		/// <summary>
		/// サーバを開始する
		/// </summary>
		public void start()
		{
			tcpServer.addEventListener(ServerEvent.NOTIFY, onTcpServerNotify);
			tcpServer.addEventListener(ServerEvent.PACKET_RECEIVED, onTcpServerPacketReceived);
			tcpServer.start();
	
			policyServer.addEventListener(ServerEvent.NOTIFY, onPolicyServerNotify);
			policyServer.start();
		}

		/// <summary>
		/// タスクバーアイコン用のフォームがロードされた時
		/// </summary>
		/// <param name="e"></param>
		private void onLoad(Event e)
		{
			FormEvent formEvent = e as FormEvent;
			if (formEvent == null)
				return;
			System.Console.WriteLine("Form Load");

			// ジョイスティック読み取り用オブジェクトの初期化
			// DirectInput をフォームのハンドル (HWND) に
			// 関連付ける必要があるため
			// メインのフォームのロード時まで初期化を遅らせる
			Global.input = new JoystickReader();
			Global.input.start(formMain.Handle);
		}

		/// <summary>
		/// タスクバーアイコン用のフォームが閉じられる時
		/// </summary>
		/// <param name="e"></param>
		private void onClosing(Event e)
		{
			System.Console.WriteLine("Form Closing");
			FormEvent formEvent = e as FormEvent;
			if (formEvent == null)
				return;
			stop();
		}

		/// <summary>
		/// サーバのメッセージを受け取るイベントハンドラ
		/// (ジョイスティックの状態を送信するサーバ用)
		/// </summary>
		/// <param name="e"></param>
		private void onTcpServerNotify(Event e)
		{
			ServerEvent serverEvent = e as ServerEvent;
			if (serverEvent == null)
				return;
			Global.logger.write(getDateTimeString() + serverEvent.message);
		}

		/// <summary>
		/// ジョイスティックの状態を送信するサーバが
		/// パケットを受信した時 (今のところ未使用)
		/// </summary>
		/// <param name="e"></param>
		private void onTcpServerPacketReceived(Event e)
		{
			ServerEvent serverEvent = e as ServerEvent;
			if (serverEvent == null)
				return;
			//Debug.WriteLine(serverEvent.packet.toString());
		}

		/// <summary>
		/// サーバのメッセージを受け取るイベントハンドラ
		/// (PolicyFileServer 用)
		/// </summary>
		/// <param name="message"></param>
		private void onPolicyServerNotify(Event e)
		{
			ServerEvent serverEvent = e as ServerEvent;
			if (serverEvent == null)
				return;
			Global.logger.write(getDateTimeString() + serverEvent.message);
		}

		/// <summary>
		/// ログ表示用
		/// 現在の日時を表す文字列を取得する
		/// </summary>
		/// <returns></returns>
		private String getDateTimeString()
		{
			DateTime now = DateTime.Now;
			return now.ToString("[yy/MM/dd HH:mm:ss] ");
		}

		/// <summary>
		/// サーバと DirectInput の停止
		/// </summary>
		public void stop()
		{
			tcpServer.stop();
			policyServer.stop();
			Global.input.stop();
		}
	}
}
